<template>
    <div ref="layoutMainScrollbarRef" class="layout-padding">
        <div class="layout-padding-auto layout-padding-view">
            <div>
                <el-input v-model="keyword" placeholder="请输入关键词" style="width: 300px;"></el-input> &nbsp;
                <el-button type="primary" icon="search" @click="search">搜索</el-button>
                <el-button @click="reset">重置</el-button>&nbsp;&nbsp;
                <el-radio-group v-model="nodeCount" @change="updateGraphData" style="font-size: 14px;">
                    <el-radio-button :label="10">10</el-radio-button>
                    <el-radio-button :label="20">20</el-radio-button>
                    <el-radio-button :label="50">50</el-radio-button>
                    <el-radio-button :label="100">100</el-radio-button>
                </el-radio-group>
            </div>
            <div style="width: 100%; height: 600px; margin-top: 20px;">
                <RelationGraph ref="relationGraph$" :data="graphData" :options="options" @node-click="onNodeClick">
                    <template #node="{ node }">
                        <div style="padding-top: 15px;" class="node-circle small-font">{{ node.text }}</div>
                    </template>
                </RelationGraph>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
    import { ref, onMounted, watch } from 'vue';
    import { useRoute } from 'vue-router';
    import { getRelationshipData } from '/@/api/know/relation';
    import RelationGraph, { RGNode, RGUserEvent } from 'relation-graph/vue3';

    // 组件和数据参考
    const relationGraph$ = ref<RelationGraph>();

    const keyword = ref('');
    const nodeCount = ref(10);
    const route = useRoute();
    const fullGraphData = ref({
        nodes: [],
        lines: []
    });
    const graphData = ref({
        nodes: [],
        lines: []
    });
    const layoutMainScrollbarRef = ref(null);

    // RelationGraph组件的选项
    const options = {
        defaultExpandHolderPosition: 'right',
        defaultLineWidth: 3,
        // defaultNodeShape: 0  默认 0   默认的节点形状，0:圆形；1:矩形
        // defaultLineShape: 1  设置线条样式 默认 直线   （1:直线 2:样式2 3:样式3 4:折线 5:样式5 6:样式6）
        // debug: true, 控制台打印日志
        // showDebugPanel: true,
    };

    // 用于处理节点点击事件的函数
    const onNodeClick = async (node: RGNode, e: RGUserEvent) => {
        try {
            const response = await getRelationshipData({ topoId: node.id });
            const data = response.data;
            if (data.length > 0) {
                const convertedData = convertListToGraph(data, keyword.value);
                fullGraphData.value = convertedData;
                setColorForAllNodes(fullGraphData.value); // 设置所有节点颜色
                updateGraphData();
            } else {
                // 如果未找到子节点，则仅显示单击的节点
                const singleNodeData = {
                    nodes: [{ id: node.id, text: node.text, color: getColorByLevel(0) }],
                    lines: []
                };
                fullGraphData.value = singleNodeData;
                updateGraphData();
            }
        } catch (error) {
            console.error('Error fetching relationship data:', error);
        }
    };

    // 获取关系数据的函数
    const fetchRelationshipData = async (keyword: string = '') => {
        try {
            const topoId = route.query.topoId;
            const response = await getRelationshipData({ topoId });
            const data = response.data;
            // 转换树形结构数据为关系图所需的格式
            const convertedData = convertListToGraph(data, keyword);
            fullGraphData.value = convertedData;
            updateGraphData();
        } catch (error) {
            console.error('获取关系数据时出错:', error);
        }
    };

    // 用于更新具有有限数量节点的图形数据的函数
    const updateGraphData = () => {
        const limitedData = limitGraphData(fullGraphData.value, nodeCount.value);
        for (let d of limitedData.nodes) {
            d.children = []
        }
        graphData.value = limitedData;
        relationGraph$.value.setJsonData(graphData.value, () => {
            console.log('RelationGraph updated!');
        });
    };

    // 函数将数据列表转换为图形结构
    const convertListToGraph = (data, keyword = '') => {
        const nodes = [];
        const lines = [];
        const idToNodeMap = {};

        // 初始化节点映射
        data.forEach(item => {
            idToNodeMap[item.id] = {
                id: item.id,
                text: item.datasourceName,
                parentId: item.relationId,
                sortOrder: item.sortOrder,
                filedSchema: item.filedSchema,
                children: [],
                // color: '' // 添加颜色属性
            };
        });

        // 过滤节点并包含其子节点
        let filteredData = data;
        if (keyword) {
            // 精确匹配搜索关键词
            const matchedNode = data.find(item => item.datasourceName === keyword);
            if (matchedNode) {
                filteredData = [matchedNode];
                const stack = [matchedNode];
                const visited = new Set();

                while (stack.length > 0) {
                    const currentNode = stack.pop();
                    visited.add(currentNode.id);

                    // 查找子节点
                    const children = data.filter(item => item.relationId === currentNode.id);
                    children.forEach(child => {
                        if (!visited.has(child.id)) {
                            stack.push(child);
                            filteredData.push(child);
                        }
                    });
                }
            } else {
                filteredData = [];
            }
        }

        // 构建树结构并生成节点和连线数据
        const addedLines = new Set();// 用于存储已经添加的连线
        const addedNodes = new Set(); // 用于存储已经添加的节点
        filteredData.forEach(item => {
            if (item.relationId !== null && item.relationId !== '0' && idToNodeMap[item.relationId]) {
                const lineKey = `${item.relationId}-${item.id}`;
                if (!addedLines.has(lineKey)) {
                    idToNodeMap[item.relationId].children.push(idToNodeMap[item.id]);
                    // 只添加直接父子节点的连线
                    lines.push({ from: item.relationId, to: item.id, text: item.filedSchema });
                    addedLines.add(lineKey);// 标记这条连线已添加
                }
            }
            // 确保节点只被添加一次
            if (!addedNodes.has(item.id)) {
                nodes.push(idToNodeMap[item.id]);
                addedNodes.add(item.id);
            }
        });

        // 对节点进行排序
        Object.values(idToNodeMap).forEach(node => {
            node.children.sort((a, b) => a.sortOrder - b.sortOrder);
        });

        // 找到根节点
        const rootNode = data.find(item => item.relationId === null || item.relationId === '0');
        // 设置节点颜色
        if (rootNode) {
            setNodeColor(idToNodeMap[rootNode.id], 0);
        }

        return { rootId: rootNode ? rootNode.id : null, nodes, lines };
    };


    const setColorForAllNodes = (graphData) => {
        if (graphData && graphData.nodes) {
            graphData.nodes.forEach((node, index) => {
                // 确定如何唯一标识节点或其属性
                let identifier = node.id; // 示例：使用节点id作为标识符

                // 示例：使用标识符（例如，节点id）来决定颜色
                node.color = getColorByLevel(index); // 以索引为例
            });
        }
    };

    const getColorByLevel = (level) => {
        const colors = ['#ffa900', '#00FF00', '#0000FF', '#FF00FF', '#1effb4', '#ff1d68', '#26c7ff', '#fffd1a', '#ffd4f0', '#daffcc', '#ff7300'];
        return colors[level % colors.length];
    };

    // 用于根据节点级别设置节点颜色的函数
    const setNodeColor = (node, level) => {
        const colors = ['#ffa900', '#00FF00', '#0000FF', '#FF00FF', '#1effb4', '#ff1d68', '#26c7ff', '#fffd1a', '#ffd4f0', '#daffcc', '#ff7300'];
        node.color = colors[level % colors.length];
        node.children.forEach(child => {
            setNodeColor(child, level + 1);
        });
    };

    // 函数将图形数据限制为指定数量的节点
    const limitGraphData = (data, limit) => {
        const nodes = data.nodes.slice(0, limit);
        const lines = data.lines.filter(line =>
            nodes.some(node => node.id === line.from) && nodes.some(node => node.id === line.to)
        );

        return { rootId: data.rootId, nodes, lines };
    };

    // 重置搜索和节点计数的功能
    const reset = () => {
        keyword.value = '';
        nodeCount.value = 1000;
        fetchRelationshipData();
    };

    // 基于关键字搜索关系数据的函数
    const search = () => {
        fetchRelationshipData(keyword.value);
    };

    // 装载组件时获取初始关系数据
    onMounted(() => {
        // 初始加载数据
        fetchRelationshipData();
    });

    // 注意nodeCount中的更改，并相应地更新图形数据
    watch(nodeCount, updateGraphData);
</script>

<style>
    .layout-padding {
        padding: 20px;
    }

    .layout-padding-auto {
        padding: 0 auto;
    }

    .node-circle {
        display: inline-block;
        width: 50px;
        height: 50px;
        border-radius: 50%;
        text-align: center;
        line-height: 50px;
        font-weight: bold;
    }

    .small-font {
        font-size: 10px; /* 调整字体大小为 12px */
    }
</style>
